package com.apache.bid.common;

import java.math.BigDecimal;

/**
 * description:  统一处理类（处理大数值）
 * @author ljshi 创建时间：2016-7-8  
 * @Copyright(c)2014:北京中百信软件技术有限公司
 */
public class BigDecimalUtil {

	private static BigDecimalUtil instance;

	private BigDecimalUtil() {
	}

	public void init() {
		instance = this;
	}

	public static BigDecimalUtil getInstance() {
		if (null == instance) {
			instance = new BigDecimalUtil();
		}
		return instance;
	}

	/**
	 * 获取一个BigDecimal对象
	 * @param value 整数 int类型
	 * @return
	 */
	public BigDecimal getBigDecimal(int value) {

		return new BigDecimal(value);
	}

	/**
	 * 获取一个BigDecimal对象
	 * @param value 长整数
	 * @return
	 */
	public BigDecimal getBigDecimal(long value) {

		return new BigDecimal(value);
	}

	/**
	 * 获取一个BigDecimal对象 (double有精度问题，不建议使用此方法)
	 * @param value 双精度数值
	 * @return
	 */
	public BigDecimal getBigDecimal(double value) {

		return new BigDecimal(value);
	}

	/**
	 * 获取一个BigDecimal对象
	 * @param value 数值型字符串
	 * @return
	 */
	public BigDecimal getBigDecimal(String value) {

		return new BigDecimal(value);
	}

	/**
	 * BigDecimal对象转换为字符
	 * @param value
	 * @return
	 */
	public String bigDecimalToStr(BigDecimal value) {

		return String.valueOf(value);
	}

	/**
	 * 两数相加
	 * @param v1 被加数
	 * @param v2 加数
	 * @return 两数的和
	 */
	public BigDecimal add(BigDecimal v1, BigDecimal v2) {

		return v1.add(v2);
	}

	/**
	 * 两数的差
	 * @param v1 被减数
	 * @param v2 减数
	 * @return 两数的差
	 */
	public BigDecimal subtract(BigDecimal v1, BigDecimal v2) {

		return v1.subtract(v2);
	}

	/**
	 * 两数相乘
	 * @param v1 被乘数
	 * @param v2 乘数
	 * @return 两数的积
	 */
	public BigDecimal multiply(BigDecimal v1, BigDecimal v2) {

		return v1.multiply(v2);
	}

	/**
	 * 两数相除
	 * @param v1 被除数 
	 * @param v2  除数
	 * @return 两数的商
	 */
	public BigDecimal divide(BigDecimal v1, BigDecimal v2) {

		return v1.divide(v2);
	}

	/**
	 * 两数相除
	 * @param v1 被除数 
	 * @param v2  除数
	 * @param scale 保留小数位数
	 * @return 两数的商（保留指定小数位）
	 */
	public BigDecimal divide(BigDecimal v1, BigDecimal v2, int scale) {

		return v1.divide(v2, scale, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 四舍五入
	 * @param val 数值
	 * @param scale 保留小数位数
	 * @return
	 */
	public BigDecimal roundHalfUp(BigDecimal val, int scale) {

		return val.setScale(scale, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 判断相等
	 * @param v1
	 * @param v2
	 * @return
	 */
	public boolean eq(BigDecimal v1, BigDecimal v2) {

		if (v1.compareTo(v2) == 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断不相等
	 * @param v1
	 * @param v2
	 * @return
	 */
	public boolean ne(BigDecimal v1, BigDecimal v2) {

		return !eq(v1, v2);
	}

	/**
	 * 判断第一个数大于第二个数
	 * @param v1
	 * @param v2
	 * @return
	 */
	public boolean gt(BigDecimal v1, BigDecimal v2) {

		if (v1.compareTo(v2) == 1) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断第一个数大于等于第二个数
	 * @param v1
	 * @param v2
	 * @return
	 */
	public boolean ge(BigDecimal v1, BigDecimal v2) {

		if (v1.compareTo(v2) >= 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断第一个数小于第二个数
	 * @param v1
	 * @param v2
	 * @return
	 */
	public boolean lt(BigDecimal v1, BigDecimal v2) {

		if (v1.compareTo(v2) == -1) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断第一个数小于等于第二个数
	 * @param v1
	 * @param v2
	 * @return
	 */
	public boolean le(BigDecimal v1, BigDecimal v2) {

		if (v1.compareTo(v2) <= 0) {
			return true;
		} else {
			return false;
		}
	}

	public static void main(String[] args) {

		BigDecimal bd = BigDecimalUtil.getInstance().getBigDecimal(10);
		System.out.println("整数 10：" + bd);
		BigDecimal lbd = BigDecimalUtil.getInstance().getBigDecimal(1000000000);
		System.out.println("整数 1000000000：" + lbd);
		//		BigDecimal dbd = BigDecimalUtil.getInstance().getBigDecimal(1000000000.123456);
		BigDecimal sbd = BigDecimalUtil.getInstance().getBigDecimal("1000000000.123456");
		//		System.out.println("整数 1000000000.123456：" + dbd);
		//		System.out.println("整数 1000000000.123456：" + BigDecimalUtil.getInstance().roundHalfUp(dbd, 4));
		//		System.out.println("整数 1000000000.123456：" + BigDecimalUtil.getInstance().roundHalfUp(dbd, 5));

		System.out.println("整数 s1000000000.123456：" + sbd);
		System.out.println("整数 s1000000000.123456：" + BigDecimalUtil.getInstance().roundHalfUp(sbd, 4));
		System.out.println("整数 s1000000000.123456：" + BigDecimalUtil.getInstance().roundHalfUp(sbd, 5));
		System.out.println();
		//		System.out.println("相加：" + BigDecimalUtil.getInstance().add(dbd, sbd));
		//		System.out.println("相减：" + BigDecimalUtil.getInstance().subtract(dbd, sbd));
		System.out.println();
		System.out.println("相加：" + BigDecimalUtil.getInstance().add(sbd, sbd));
		System.out.println("相减：" + BigDecimalUtil.getInstance().subtract(sbd, sbd));
		System.out.println();
		System.out.println("相乘：" + BigDecimalUtil.getInstance().multiply(bd, bd));
		System.out.println("相除：" + BigDecimalUtil.getInstance().divide(bd, bd));
		System.out.println();
		System.out.println("相乘：" + BigDecimalUtil.getInstance().multiply(lbd, lbd));
		System.out.println("相除：" + BigDecimalUtil.getInstance().divide(lbd, lbd));

		System.out.println("=====================");
		System.out.println("比较相等：" + BigDecimalUtil.getInstance().eq(lbd, new BigDecimal(1000000000)));
		System.out.println("比较不相等：" + BigDecimalUtil.getInstance().ne(lbd, sbd));
		System.out.println("=====================");
		System.out.println("比较大于：" + BigDecimalUtil.getInstance().gt(lbd, new BigDecimal(100000000)));
		System.out.println("比较小于：" + BigDecimalUtil.getInstance().lt(lbd, new BigDecimal(1000000001)));
		System.out.println("=====================");
		System.out.println("比较大于等于：" + BigDecimalUtil.getInstance().ge(lbd, new BigDecimal(100000000)));
		System.out.println("比较大于等于：" + BigDecimalUtil.getInstance().ge(lbd, new BigDecimal(1000000000)));
		System.out.println("比较大于等于：" + BigDecimalUtil.getInstance().ge(lbd, new BigDecimal(1000000001)));

		System.out.println("比较小于等于：" + BigDecimalUtil.getInstance().le(lbd, new BigDecimal(1000000001)));
		System.out.println("比较小于等于：" + BigDecimalUtil.getInstance().le(lbd, new BigDecimal(1000000000)));
		System.out.println("比较小于等于：" + BigDecimalUtil.getInstance().le(lbd, new BigDecimal(100000000)));
		System.out.println(Integer.MAX_VALUE);
		System.out.println(Long.MAX_VALUE);
		System.out.println("1000000000：" + BigDecimalUtil.getInstance().getBigDecimal(9990000000L));
		System.out.println("9990000000L：" + BigDecimalUtil.getInstance().getBigDecimal(9990000000L));
		System.out.println("92233720368547758070000000000000000:"
				+ BigDecimalUtil.getInstance().getBigDecimal("92233720368547758070000000000000000"));

		System.out.println("===================");
		System.out.println(new BigDecimal("92233720368547758070000000000000000123456789012345678901234567890"));

		System.out.println("===================");
		System.out.println("92233720368547758070000000000000000:"
				+ BigDecimalUtil.getInstance().getBigDecimal("92233720368547758070000000000000000")
						.add(new BigDecimal(1)));
	}
}
